#include <gtest/gtest.h>
#include "common_components/common_runtime/src/heap/collector/gc_request.h"
#include "common_components/common_runtime/src/heap/collector/gc_stats.h"
 #include "common_components/common_runtime/src/base/time_utils.h"

using namespace panda;

// 模拟当前时间
uint64_t fakeCurrentTime = 0;

// 替换 TimeUtil::NanoSeconds()
namespace panda {
uint64_t TimeUtil::NanoSeconds() {
    return fakeCurrentTime;
}
} // namespace panda

class GCRequestTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 初始时间设为 0
        fakeCurrentTime = 0;
    }

    void SetPrevRequestTime(GCRequest& req, uint64_t time) {
        req.SetPrevRequestTime(time);
    }

    void SetMinInterval(GCRequest& req, uint64_t intervalNs) {
        req.SetMinInterval(intervalNs);
    }
};

// 辅助函数：设置上一次 GC 完成时间
void SetLastGCFinishTime(uint64_t time) {
    GCStats::SetPrevGCFinishTime(time);
}

// 工具函数：检查是否被忽略
bool ShouldBeIgnoredWithReason(GCReason reason, uint64_t minIntervalNs, uint64_t prevReqTime, uint64_t now,
                               uint64_t lastGCFinishTime = 0) {
    fakeCurrentTime = now;
    SetLastGCFinishTime(lastGCFinishTime);

    GCRequest req = {
        reason,
        "", // name
        false, // isSync
        false, // isConcurrent
        minIntervalNs,
        prevReqTime
    };

    return req.ShouldBeIgnored();
}

// ------------------ 测试用例 ------------------

TEST_F(GCRequestTest, ShouldBeIgnored_Heu_ReturnsTrue_IfFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_HEU,
        1000,          // minIntervalNs
        fakeCurrentTime - 500, // prevReqTime < now - minInterval → 频繁触发
        fakeCurrentTime
    );
    EXPECT_TRUE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_Heu_ReturnsFalse_IfNotFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_HEU,
        1000,
        fakeCurrentTime - 1500, // prevReqTime > now - minInterval
        fakeCurrentTime
    );
    EXPECT_FALSE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_Native_ReturnsTrue_IfFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_NATIVE,
        1000,
        fakeCurrentTime - 500,
        fakeCurrentTime,
        fakeCurrentTime - 500 // lastGCFinishTime
    );
    EXPECT_TRUE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_Native_ReturnsFalse_IfNotFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_NATIVE,
        1000,
        fakeCurrentTime - 1500,
        fakeCurrentTime,
        fakeCurrentTime - 1500
    );
    EXPECT_FALSE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_OOM_ReturnsTrue_IfFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_OOM,
        1000,
        fakeCurrentTime - 500,
        fakeCurrentTime
    );
    EXPECT_TRUE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_OOM_ReturnsFalse_IfNotFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_OOM,
        1000,
        fakeCurrentTime - 1500,
        fakeCurrentTime
    );
    EXPECT_FALSE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_Force_ReturnsTrue_IfFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_FORCE,
        1000,
        fakeCurrentTime - 500,
        fakeCurrentTime
    );
    EXPECT_TRUE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_Force_ReturnsFalse_IfNotFrequent) {
    bool result = ShouldBeIgnoredWithReason(
        GC_REASON_FORCE,
        1000,
        fakeCurrentTime - 1500,
        fakeCurrentTime
    );
    EXPECT_FALSE(result);
}

TEST_F(GCRequestTest, ShouldBeIgnored_User_ReturnsFalse) {
    fakeCurrentTime = 1000;

    GCRequest req = {
        GC_REASON_USER,
        "",
        false,
        false,
        0,
        0
    };

    EXPECT_FALSE(req.ShouldBeIgnored());
}
